<template>
  <div>
    <div class="style">
      <div class="style-t">
        <div class="style-t-l">{{ time }}</div>
        <div class="style-t-r">{{ date }}</div>
      </div>
      <div class="style-c">
        <div
          @click="toggleStyle(item.show, index)"
          :class="{ active: item.show }"
          v-for="(item, index) in styleList"
          :key="index"
        >
          {{ item.title }}
        </div>
      </div>
      <div class="style-b">
        <div
          @click="toggleWeather(item.show, index)"
          :class="{
            'active-weather': item.show
          }"
          v-for="(item, index) in weatherList"
          :key="item.icon"
        >
          <Icon
            :title="item.title"
            :name="item.icon"
            :font-size="28"
          />
          <div>{{ item.title }}</div>
        </div>
      </div>
      <!-- 车流水流测试 -->
      <div class="style-test">
        <el-button
          type="text"
          @click="handleCarLine"
          :class="{ active: carActive }"
          >车流</el-button
        >
        <el-button
          type="text"
          @click="handleWaterLine"
          :class="{ active: waterActive }"
          >水流</el-button
        >
      </div>
    </div>
    <div class="temp-close" @click="close"></div>
  </div>
</template>

<script>
import Icon from '@/components/icon'
import { getAction } from '@/utils/helper'
import PolylineTrailLinkMaterialProperty from '@/utils/extension/polylineTrailLinkMaterialProperty'

const mapViewer = {}
const style = {}
const weather = {}
const timer = {}

// 测试使用车流轨迹
const carLines = [
  [
    { x: 104.32587554734452, y: 30.356448545561488 },
    { x: 104.32821626916267, y: 30.357488963779414 },
    { x: 104.33014340399609, y: 30.3582831669214 },
    { x: 104.33158134122479, y: 30.358897436267466 },
    { x: 104.33314487934175, y: 30.359561826618172 },
    { x: 104.33457115929593, y: 30.360208818054073 },
    { x: 104.33595581365472, y: 30.3609098591438 }
  ],
  [
    { x: 104.34089680385478, y: 30.362248653084077 },
    { x: 104.34364674098124, y: 30.3623391883389 },
    { x: 104.34565583295857, y: 30.362454485613465 },
    { x: 104.3479181522458, y: 30.36263086662413 },
    { x: 104.34946853569069, y: 30.36273504018325 },
    { x: 104.35159048544196, y: 30.3629916164824 },
    { x: 104.35363427774408, y: 30.363139938213983 },
    { x: 104.35566459548765, y: 30.36314002018191 }
  ]
]
// 测试使用汽车s3m模型
const carModelUrls = [
  'http://support.supermap.com.cn:8090/webgl/examples/webgl/data/car/qiche1.s3m',
  'http://support.supermap.com.cn:8090/webgl/examples/webgl/data/car/qiche2.s3m'
]
const keymap = {}

// 测试使用水流区域
const waterRegion = [
  104.32472746394393, 30.3624775400823, 100,
  104.34495850052063, 30.364090858314807, 100
]

let carLineLayer
let carLineTimeInterval

let waterEntity

export default {
  inject: ['viewerId'],
  components: {
    Icon
  },
  data() {
    return {
      time: '',
      date: '',
      styleList: [],
      weatherList: [],
      carActive: false,
      waterActive: false
    }
  },
  async created() {
    const { toolManager } = await getAction(this.viewerId)
    mapViewer[this.viewerId] = toolManager.viewer
    style[this.viewerId] = toolManager.style
    this.styleList = style[this.viewerId].map((style) => {
      const { title, visible, set } = style
      const show = visible()
      return {
        title,
        show,
        set
      }
    })
    weather[this.viewerId] = toolManager.weather
    this.weatherList = weather[this.viewerId].map(
      (weather) => {
        const { title, icon, visible, set } = weather
        const show = visible()
        return {
          title,
          icon,
          show,
          set
        }
      }
    )
    timer[this.viewerId] = setInterval(() => {
      const now = new Date()
      const h = now.getHours()
      const m = now.getMinutes()
      const s = now.getSeconds()
      this.time = `${h < 10 ? '0' + h : h}:${
        m < 10 ? '0' + m : m
      }:${s < 10 ? '0' + s : s}`
      const Y = now.getFullYear()
      const M = now.getMonth() + 1
      const D = now.getDate()
      const dateArr = [
        '日',
        '一',
        '二',
        '三',
        '四',
        '五',
        '六'
      ]
      const W = dateArr[new Date().getDay()]
      this.date = `${Y}-${M < 10 ? '0' + M : M}-${
        D < 10 ? '0' + D : D
      } 星期${W}`
    })
  },
  beforeDestroy() {
    window.clearInterval(timer[this.viewerId])
  },
  methods: {
    toggleStyle(show, index) {
      this.styleList[index].set(!show)
      this.$set(this.styleList[index], 'show', !show)
    },
    toggleWeather(show, index) {
      this.weatherList[index].set(!show)
      this.$set(this.weatherList[index], 'show', !show)
    },
    close() {
      this.clearCarLine()
      this.clearWaterLine()
      this.$emit('close')
    },
    // 车流点击
    handleCarLine() {
      if (!carLineLayer) {
        carModelUrls.forEach((item) => {
          keymap[item] = []
        })

        carLineLayer = new Cesium.DynamicLayer3D(
          mapViewer[this.viewerId].scene.context,
          carModelUrls
        )
        mapViewer[this.viewerId].scene.primitives.add(
          carLineLayer
        )
        const count = carLines.length
        const objects = []
        let state
        let index
        for (let i = 0; i < count; i++) {
          for (let j = 0; j < carModelUrls.length; j++) {
            const url = carModelUrls[j]
            const pts = carLines[i]
            const len = pts.length
            index = Math.floor(Math.random() * (len - 1))
            let dir = true
            if (j === 0) {
              index = 0
              dir = true
            }
            const point = pts[index]
            if (!point) {
              continue
            }
            state = new Cesium.DynamicObjectState({
              longitude: point.x,
              latitude: point.y,
              altitude: point.z || 0,
              scale: new Cesium.Cartesian3(10, 10, 10)
            })
            objects.push({
              state: state,
              dir: dir,
              index: index,
              origin: index
            })
            keymap[url].push(state)
          }
        }
        if (carLineTimeInterval) {
          clearInterval(carLineTimeInterval)
        }
        carLineTimeInterval = setInterval(() => {
          let m = 0
          for (let i = 0; i < count; i++) {
            const pts = carLines[i]
            if (pts.length === 0) {
              m += 1
              continue
            }
            for (let j = 0; j < carModelUrls.length; j++) {
              const url = carModelUrls[j]
              const obj =
                objects[(i - m) * carModelUrls.length + j]
              const state = obj.state
              const dir = obj.dir
              let point
              if (dir) {
                obj.index += 1
                point = pts[obj.index]
                if (!point) {
                  carLineLayer.clearState(url, [state.id])
                  obj.index = 1
                  point = pts[obj.index]
                }
              }
              if (point) {
                state.longitude = point.x
                state.latitude = point.y
                state.altitude = point.z || 0
              }
            }
          }
          for (const key in keymap) {
            carLineLayer.updateObjectWithModel(
              key,
              keymap[key]
            )
          }
        }, 400)
        carLineLayer.updateInterval = 400
        this.carActive = true
      } else {
        this.clearCarLine()
        this.carActive = false
      }
    },
    // 清除车流
    clearCarLine() {
      if (carLineTimeInterval) {
        clearInterval(carLineTimeInterval)
      }
      if (carLineLayer) {
        mapViewer[this.viewerId].scene.primitives.remove(
          carLineLayer
        )
        carLineLayer = null
      }
    },
    handleWaterLine() {
      if (!waterEntity) {
        waterEntity = new Cesium.Entity({
          name: 'river',
          polyline: {
            positions:
              Cesium.Cartesian3.fromDegreesArrayHeights(
                waterRegion
              ),
            width: 200,
            followSurface: true,
            material:
              new Cesium.PolylineTrailLinkMaterialProperty(
                Cesium.Color.SKYBLUE,
                10000
              ),
            clampToGround: true,
            distanceDisplayCondition:
              new Cesium.DistanceDisplayCondition(0, 30000)
          }
        })
        mapViewer[this.viewerId].entities.add(waterEntity)
        this.waterActive = true
      } else {
        this.clearWaterLine()
        this.waterActive = false
      }
    },
    clearWaterLine() {
      if (waterEntity) {
        mapViewer[this.viewerId].entities.remove(
          waterEntity
        )
        waterEntity = null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.style {
  background: #193b51;
  box-shadow: 0 0 6px 0 rgba(20, 20, 20, 0.5);
  border-radius: 2px;
  display: flex;
  flex-direction: column;
  width: 290px;

  & > div {
    padding: 14px;
  }

  & > div:not(:first-child) {
    border-top: 1px solid rgba(255, 255, 255, 0.2);
  }

  &-t {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;

    &-l {
      font-size: 34px;
      line-height: 30px;
    }

    &-r {
      font-size: 12px;
      line-height: 20px;
    }
  }

  &-c {
    flex: 1;
    display: grid;
    grid-template-columns: repeat(3, auto);
    grid-row-gap: 14px;
    grid-column-gap: 11px;

    & > div {
      cursor: pointer;
      border-radius: 2px;
      padding: 4px 0;
      font-size: 12px;
      font-weight: 400;
      border: 1px solid rgba(255, 255, 255, 0.4);
      color: #fff;
      text-align: center;
    }

    .active {
      border: 1px solid rgb(0, 210, 255);
      color: rgb(0, 210, 255);
    }
  }

  &-b {
    display: flex;
    align-items: center;
    justify-content: space-around;

    & > div {
      cursor: pointer;
      display: flex;
      flex-direction: column;
      align-items: center;
      font-size: 14px;
      color: #fff;
    }
  }

  &-test {
    display: flex;
    justify-content: space-around;

    .el-button {
      color: white;

      &.active {
        color: rgb(0, 210, 255);
      }
    }
  }

  .active-weather {
    color: rgba(255, 177, 64, 1);
  }
}

.temp-close {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 16px;
  height: 16px;
  background-color: red;
  border-radius: 50%;
  cursor: pointer;

  &::after,
  &::before {
    content: '';
    width: 50%;
    height: 1px;
    position: absolute;
    top: 50%;
    left: 50%;
    background-color: #fff;
  }

  &::before {
    transform: translateX(-50%) translateY(-50%)
      rotateZ(45deg);
  }

  &::after {
    transform: translateX(-50%) translateY(-50%)
      rotateZ(-45deg);
  }
}
</style>
